﻿package org.openChart.meta 
{
	import org.openChart.meta.Style;
	
	/**
	 * The base class of Axes.
	 * 
	 * @author Chongyuan	 
	 * */
	public class Axis extends BaseObject
	{
		// The labels of axis.
		private var labels_:Array;
		// The sticks of axis.
		private var sticks_:Array;
		// The title of axis.
		private var title_:TextLabel;
		
		// The minimum value .
		private var minValue_:Number = Number.MAX_VALUE;
		// The maximum value .
		private var maxValue_:Number = Number.MIN_VALUE;
		// The step.
		private var step_:Number = 1;
		
		public function Axis(object:Style) 
		{
			labels_ = new Array();
			sticks = new Array();
			super(object);
		}
		
		/**
		 * Initializing labels if max-value is larger than min-value.
		 * @param	style
		 */
		public function initLabels( style:Style ):void
		{
			if (maxValue_ > minValue)
			{
				removeAllLabels();
				resize();
				var labelCount:uint = (maxValue_ - minValue_) / step_;
				for ( var i:uint = 0 ; i <= labelCount ; i ++ )
				{
					addLabel(style, new String(minValue_ + i * step_ ));
				}
			}
		}
		
		public function reInitLabels():void
		{
			var label:TextLabel = labels_[0] as TextLabel;
			if (label)
			{
				var style:Style = label.getStyle();
				initLabels(style);
			}
		}
		/**
		 * Resize the step to make the count of labels not too little or big.
		 */
		public function resize():void
		{
			if (minValue_ > maxValue_)
				throw new Error("The min-value is larger than max-value.");
			var labelCount:Number = (maxValue_ - minValue_) / step_;
			if (labelCount < 3 || labelCount > 10)
			{
				resetStep();
				minValue_ = int(minValue_ / step_) * step_;
				maxValue_ = (int(maxValue_  / step_) + 1) * step_;
			}
		}
		
		public function resetStep():void
		{
			var labelCount:Number = (maxValue_ - minValue_) / step_;
			if (labelCount > 10)
			{
				step_ *= 10;
				resetStep();
			}
			else if (labelCount < 1)
			{
				step_ /=  10;
				resetStep();
			}
			
		}
		
		/**
		 * Remove all labels from axis.
		 */
		public function removeAllLabels():void
		{
			var length:uint = labels_.length;
			for (var i:uint = 0; i < length; i++ )
			{
				labels_.pop();
			}
		}
		
		/**
		 * Add a label to the axis.
		 * @param	style
		 * @param	text
		 */
		public function addLabel(style:Style, text:String):void
		{
			var label:TextLabel = new TextLabel(style, text);
			labels_.push(label);
		}
		
		public function get labels():Array
		{
			return this.labels_;
		}
		
		public function set labels(labels_:Array):void
		{
			this.labels_ = labels_;
		}
		
		public function set sticks( sticks_:Array ):void
		{
			this.sticks_ = sticks_;
		}
		
		public function get sticks():Array
		{
			return this.sticks_;
		}
		
		public function set title( title_:TextLabel ):void
		{
			this.title_ = title_;
		}
		
		public function get title():TextLabel
		{
			return this.title_;
		}
		
		public function set minValue( minValue_:Number ):void
		{
			this.minValue_ = minValue_;
		}
		
		public function get minValue():Number
		{
			return this.minValue_;
		}
		
		public function set maxValue( maxValue_:Number ):void
		{
			this.maxValue_ = maxValue_;
		}
		
		public function get maxValue():Number
		{
			return this.maxValue_;
		}
		
		public function set step( step_:Number ):void
		{
			this.step_ = step_;
		}
		
		public function get step():Number
		{
			return this.step_;
		}
		
		public function toString():String
		{
			var str:String = "Object:Axis \n";
			str += "[title=" + title + "]";
			str += "[max-value=" + maxValue + "]";
			str += "[min-value=" + minValue + "]";
			str += "[step=" + step + "]";
			str += "[labels=";
			for (var i:uint = 0; i < labels_.length; i++ )
			{
				str += labels[i];
			}
			str += "][sticks=";
			for (var j:uint = 0; j < sticks_.length; j++ )
			{
				str += sticks[j];
			}
			str += "]";
			return str;
		}
	}
	
}